/*   
 * Copyright 2009-2010 Rob Schoening
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 *    
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.beaconframework.vaadin.ui;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.util.HierarchicalContainer;
import com.vaadin.ui.AbstractSelect;
import com.vaadin.ui.Tree;

public class SimpleTree extends Tree {
    /**
	 * 
	 */
    private static final long serialVersionUID = 1L;

    public class MyValueChangeListener implements Property.ValueChangeListener {

        /**
		 * 
		 */
        private static final long serialVersionUID = 1L;


        public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) {

            Integer itemId = (Integer) event.getProperty().getValue();

            Item item = getItem(itemId);

            if (item != null) {

                onItemSelected(item);

                Property.ValueChangeListener l = lmap.get(itemId);

                if (l != null) {

                    l.valueChange(event);

                }
            }

        }

    }

    public class SimpleTreeContainer extends HierarchicalContainer {

        /**
		 * 
		 */
        private static final long serialVersionUID = 1L;


        public SimpleTreeContainer() {
            super();

            addContainerProperty("id", Integer.class, 0);
            addContainerProperty("name", String.class, "name");
            addContainerProperty("displayName", String.class, "display name");
            setItemCaptionPropertyId("displayName");
            setItemCaptionMode(AbstractSelect.ITEM_CAPTION_MODE_PROPERTY);
        }


        public Item addChild(Item parent, String key, String display) {

            Integer childItemId = (Integer) addItem();
            Item child = getItem(childItemId);

            child.getItemProperty("id").setValue(childItemId);
            child.getItemProperty("name").setValue(key);
            child.getItemProperty("displayName").setValue(display);

            if (parent != null) {
                setChildrenAllowed(parent.getItemProperty("id").getValue(),
                        true);
                setChildrenAllowed(childItemId, false);
                setParent(childItemId, parent.getItemProperty("id").getValue());
            }
            return child;

        }

    }

    static Logger log = LoggerFactory.getLogger(SimpleTree.class);

    Map<Integer, Property.ValueChangeListener> lmap;

    SimpleTreeContainer myContainer;


    public SimpleTree() {
        super();
        init();
    }


    public SimpleTree(String caption) {
        super(caption);
        init();
    }


    public Item addNode(Item parent, String key, String display) {
        return myContainer.addChild(parent, key, display);
    }


    public Item addRootNode(String key, String display) {
        return addNode(null, key, display);
    }


    protected void init() {
        myContainer = new SimpleTreeContainer();
        setContainerDataSource(myContainer);
        addListener(new MyValueChangeListener());
        setImmediate(true);
        lmap = Collections
                .synchronizedMap(new HashMap<Integer, Property.ValueChangeListener>());
    }


    public void onItemSelected(Item item) {
        log.debug("Selected: " + item);
    }


    public void setItemListener(Item item, Property.ValueChangeListener listener) {

        lmap.put((Integer) item.getItemProperty("id").getValue(), listener);
    }
}
